package com.unibuy.smartdevice.ui;

import static android.view.View.VISIBLE;

import android.Manifest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.telephony.CellInfo;
import android.telephony.CellInfoLte;
import android.telephony.CellSignalStrengthLte;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.hoho.android.usbserial.driver.UsbSerialDriver;
import com.hoho.android.usbserial.driver.UsbSerialPort;
import com.hoho.android.usbserial.driver.UsbSerialProber;
import com.unibuy.smartdevice.AppCompatActivityAbstract;
import com.unibuy.smartdevice.FragmentAbstract;
import com.unibuy.smartdevice.HomeActivity;
import com.unibuy.smartdevice.MainActivity;
import com.unibuy.smartdevice.MyApp;

import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import com.unibuy.smartdevice.R;
import com.unibuy.smartdevice.controller.DevXinYuanController;
import com.unibuy.smartdevice.database.SlotsDao;
import com.unibuy.smartdevice.databinding.ActivityFontendBinding;
import com.unibuy.smartdevice.devices.DevNFCPay;
import com.unibuy.smartdevice.devices.Rs232Dev;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsFileNullException;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsParseException;
import com.unibuy.smartdevice.exception.LogsSettingEmptyException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.external.HttpAPI;
import com.unibuy.smartdevice.tools.HandlerMainCountdown;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.HandlerMainScheduler;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.tools.Tools;
import com.unibuy.smartdevice.ui.dialog.BuyDialog;
import com.unibuy.smartdevice.ui.dialog.FontendPickupCodeDialog;
import com.unibuy.smartdevice.ui.devs.electric.ElectricFragment;
import com.unibuy.smartdevice.ui.tools.ImageGlide;
import com.unibuy.smartdevice.ui.tools.VideoEoxPlayer;
import com.unibuy.smartdevice.ui.devs.flower.FlowerFragment;
import com.unibuy.smartdevice.utils.LanguageHelper;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.hivemq.client.mqtt.MqttClient;
import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient;
import com.hivemq.client.mqtt.mqtt3.message.publish.Mqtt3Publish;

import java.nio.charset.StandardCharsets;

public class FontendActivity extends AppCompatActivityAbstract {
    public enum Option {
        TOAST(0),
        BUY_DIALOG_OPEN(1),
        ADD_PRODUCT(2),
        STOP_COUNTDOWN(3),
        RESET_DATA(4),
        REPORT_AND_SHOT_TIME(5),
        SET_NETWORK(6),
        RESET_SLOTNO(49),
        RESTART_HOST(7),
        OPEN_CABINET_NO(85),
        HIDDEN_MULTILANGUAGE_BUTTON(8),
        SHOW_MULTILANGUAGE_BUTTON(9),
        ;

        private int option;

        public int getOption() {
            return option;
        }

        Option(int option) {
            this.option = option;
        }
    }

    public static final Map<Integer, Option> optionMap = new HashMap<>();
    static {
        for (Option option : Option.values()) {
            optionMap.put(option.getOption(), option);
        }
    }

    private ActivityFontendBinding binding;
    private Fragment activeFragment;
    private Fragment flowerFragment;
    private Fragment electricFragment;
    private static ReportShotTimeByScheduler reportOnScheduler;
    private ConnectivityManager connectivityManager;
    private ConnectivityManager.NetworkCallback networkCallback;
    private Mqtt3AsyncClient mqttClient;

    private Handler idleHandler = new Handler();
    private Runnable idleRunnable;
    private static final long IDLE_TIMEOUT = 10 * 60 * 1000; // 5 分鐘
    private double machineDetectTemp;
    UsbManager usbManager;
    UsbSerialProber prober;

    private static VideoEoxPlayer videoEoxPlayer;

    @Override
    protected Context setCtx() {
        return this;
    }

    @Override
    protected Class<?> setCls() {
        return this.getClass();
    }

    @Override
    protected HandlerMain setHandlerMain() {
        return new ToastHandlerMain(getCtx(), getLogs()) {
            private AddProductOnCountdown addProductOnCountdown;

            @Override
            protected void execute(Context context, int commandCode, String message) {
                Option option = optionMap.get(commandCode);

                switch (option) {
                    case TOAST:
                            super.execute(context, commandCode, message);
                        break;
                    case BUY_DIALOG_OPEN:
                        start(getClass().getSimpleName(), Option.STOP_COUNTDOWN.getOption(), "stop countdown");

                        if (MyApp.getInstance().getBuyList().isEmpty()) {
                            start(getClass().getSimpleName(), getString(R.string.no_products_purchased));
                        } else {
                            new BuyDialog(context, this).show();
                        }
                        break;
                    case ADD_PRODUCT:
                        if (!message.isEmpty()) {
                            super.execute(context, commandCode, message);
                        }
                        addProductOnCountdown = new AddProductOnCountdown(getHandlerMain());
                        addProductOnCountdown.start(40);
                        ((FragmentAbstract) flowerFragment).getHandlerMain().start(getClass().getSimpleName(), FlowerFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
                        if (MyApp.getInstance().getDevSet().isElectic()) {
                            ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.ADD_PRODUCT_OPEN.getOption(), "add product open");
                        }
                        break;
                    case STOP_COUNTDOWN:
                        if (addProductOnCountdown != null && addProductOnCountdown.getCountdown() > 0)
                            addProductOnCountdown.shutdown();
                        ((FragmentAbstract) flowerFragment).getHandlerMain().start(getClass().getSimpleName(), FlowerFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
                        if (MyApp.getInstance().getDevSet().isElectic()) {
                            ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.ADD_PRODUCT_CLOSE.getOption(), "add product close");
                        }
                        break;
                    case RESET_DATA:
                        ((FragmentAbstract) flowerFragment).getHandlerMain().start(getClass().getSimpleName(), FlowerFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
                        if (MyApp.getInstance().getDevSet().isElectic()) {
                            ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "shipped product");
                        }
                        saveData();
                        break;
                    case REPORT_AND_SHOT_TIME:
                        String ver = "";
                        try {
                            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
                            ver = packageInfo.versionName;
                        } catch (PackageManager.NameNotFoundException e) {
                            ver = "0";
                        }

                        binding.textVersion.setText(MyApp.getInstance().getMachine().getMachineID()+" Ver " + ver);

                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                        String timeByNow = sdf.format(new Date());
                        binding.textTime.setText(timeByNow);

                        String timeByM = new SimpleDateFormat("HH:mm").format(new Date());
                        if (timeByM.equals("23:45")) {
                            new NfcCheckout(this).start();
                        }

                        //這裡判斷每5分鐘去跑連線下位機的狀態
                        String minutePart = timeByM.split(":")[1]; // 取得 "mm" 部分
//                        if (minutePart.equals("00") || minutePart.equals("05") || minutePart.equals("10") || minutePart.equals("15") ||
//                                minutePart.equals("20") || minutePart.equals("25") || minutePart.equals("30") || minutePart.equals("35")||
//                                minutePart.equals("40") || minutePart.equals("45") || minutePart.equals("50") || minutePart.equals("55")) {
//                            getLogs().info("當前時間：" + timeByM + "，符合條件，執行 RunToADPage...");
//                            new DetectTemp(this).start();
//                        }

                        getLogs().update("ThreadCount", String.valueOf(Tools.threadCount()));
                        String tc = getLogs().getMessage();
                        getLogs().update("ViceoCount", String.valueOf(VideoEoxPlayer.getExoPlayerTotal()));
                        String vc = getLogs().getMessage();
                        binding.textThreadCount.setText("TC:" + tc + " VC:" + vc);
                        getLogs().clearMessage();

                        Tools.threadInfos();

                        String networkDevice = getNetworkDevice();
                        getLogs().update("Network", networkDevice);
                        binding.textNetwork.setText(getString(R.string.network)+"："+getLogs().getMessage());
                        getLogs().clearMessage();

//                        getLogs().update("Temperature", String.valueOf(DevXinYuanController.getTemperature()),"℃");
                        DevXinYuanController.setTemp(machineDetectTemp);
                        getLogs().update("Temperature", String.valueOf(machineDetectTemp),"℃");
                        binding.textTemperature.setText(getString(R.string.temp)+": " + machineDetectTemp +"°C");
                        getLogs().clearMessage();

                        try {
                            httpAPI.detectHost();
                        } catch (LogsParseException | LogsSettingEmptyException e) {
                            getLogs().warning(e);
                        }

                        String timeByS = new SimpleDateFormat("ss").format(new Date());
                        timeByS = String.valueOf(Integer.valueOf(timeByS)/10*10);
                        getLogs().debug("timeByS:" + timeByS);

                        if (timeByS.equals("0") || timeByS.equals("10") || timeByS.equals("20") || timeByS.equals("30") || timeByS.equals("40") || timeByS.equals("50")) {
                            if (MyApp.getInstance().getDevSet().isElectic()) {
                                ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.BUY_ON_THREAD_TIMER_TASK.getOption(), "BUY_ON_THREAD_TIMER_TASK");
                            }
                        }

                        if (timeByS.equals("30")) {
                            if (MyApp.getInstance().getDevSet().isElectic()) {
                                ((FragmentAbstract) electricFragment).getHandlerMain().start(getClass().getSimpleName(), ElectricFragment.Option.SHIPPED_PRODUCT.getOption(), "BUY_ON_THREAD_TIMER_TASK");
                            }
                        }

                        break;
                    case SET_NETWORK:
                        getLogs().info("網路："+message);
                        binding.textNetwork.setText(message);
                        break;
                    case RESTART_HOST:
                        new RestartHost(this).start();
                        break;
                    case RESET_SLOTNO:
                        new ResetSlotNo(this).start();
                        break;
                    case OPEN_CABINET_NO:
                        new RemoteDelivery(this).start();
                        break;
                    case HIDDEN_MULTILANGUAGE_BUTTON:
                        getLogs().info("隱藏多國語按紐");
//                        hiddenMultiLanguageButton();
                        break;
                    case SHOW_MULTILANGUAGE_BUTTON:
                        getLogs().info("顯示多國語按紐");
//                        showMultiLanguageButton();
                        break;
                }
            }
        };
    }

    private HttpAPI httpAPI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 讀取最後設定語言的設定
        LanguageHelper.applySavedLanguage(this);
        binding = ActivityFontendBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        httpAPI = new HttpAPI(getHandlerMain());
        machineDetectTemp = 0.0;

        this.connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);

        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        prober = UsbSerialProber.getDefaultProber();

        setBottomNavigation();
        startOnSwitchFragment();

        //啟動MQTT
        setupMQTT();
        //啟動溫度偵測
        try {
            RunDetectTemp();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void setupMQTT() {
        mqttClient = MqttClient.builder()
                .useMqttVersion3()
                .identifier("android-client-" + System.currentTimeMillis())
                .serverHost("broker.hivemq.com") // 或你自己的 MQTT 伺服器
                .serverPort(1883) // WebSocket 用 8000 或 8884 (SSL)，TCP 用 1883
                .buildAsync();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mqttClient.connect()
                    .whenComplete((connAck, throwable) -> {
                        if (throwable == null) {
                            Log.d("MQTT", "✅ 連線成功！");
                            subscribeToTopic();
                        } else {
                            Log.e("MQTT", "❌ 連線失敗：" + throwable.getMessage());
                        }
                    });
        }
    }

    private void subscribeToTopic() {
        mqttClient.subscribeWith()
                .topicFilter("smartdevice/reset/flower")
                .callback(this::handleMessage)
                .send();
    }

    private void handleMessage(Mqtt3Publish publish) {
        String payload = new String(publish.getPayloadAsBytes(), StandardCharsets.UTF_8);
        Log.d("MQTT", "收到訊息：" + payload);

        if (payload.equalsIgnoreCase("restartAPP")) {
            restartApp();
        }else if (payload.equalsIgnoreCase("reloadAD")){
            reloadAD();
        }else if (payload.equalsIgnoreCase("reloadAD2")){
            reloadAD2();
        }
    }

    public void restartApp() {
        Intent intent = new Intent(getApplicationContext(), FontendActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE);

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.setExact(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent);

        android.os.Process.killProcess(android.os.Process.myPid());
    }

    private void reloadAD(){
        try {
            httpAPI.downloadAdvertisement(() -> {
                getLogs().info("✅ reloadAD 完成，準備重啟 APP");
                restartApp();
            });
        } catch (LogsParseException | LogsSettingEmptyException e) {
            getLogs().warning(e);
        }
    }

    private void reloadAD2(){
        try {
            httpAPI.downloadAdvertisement();
        } catch (LogsParseException | LogsSettingEmptyException e) {
            getLogs().warning(e);
        }
    }

public void startOnSwitchFragment() {
        try {
            if (videoEoxPlayer != null) {
                videoEoxPlayer.videoStop(); // 確保舊的播放停止
            }

            // **確保 ExoPlayer 已完全釋放**
            Thread.sleep(100);

            if (MyApp.getInstance().getFontendAdUrlString().size() == 1) {
                String mediaUri = MyApp.getInstance().getFontendAdUrlString().get(0);
                boolean isImage = mediaUri.endsWith(".png") || mediaUri.endsWith(".jpg") || mediaUri.endsWith(".gif");
                if (isImage) {
                    videoEoxPlayer = null;
                    binding.videoView.setVisibility(View.GONE);
                    binding.imageAd.setVisibility(VISIBLE);

                    Glide.with(getCtx()).load(mediaUri)
                            .placeholder(R.drawable.loading)
                            .error(R.drawable.loading)
                            .transform(new ImageGlide.WhiteTintTransformation(128))
                            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
                            .into(binding.imageAd);
                }
            } else {
                binding.videoView.setVisibility(VISIBLE);
                binding.imageAd.setVisibility(View.GONE);

                videoEoxPlayer = new VideoEoxPlayer(getCtx()); // 重新初始化播放器
                videoEoxPlayer.videoPlay(binding.videoView, SlotField.VMC.getField()); // 確保 PlayerView 綁定
            }
        } catch (LogsFileNullException | LogsEmptyException | InterruptedException e) {
            getLogs().warning(e);
        }
    }

    public void stopOnSwitchFragment() {
        if (videoEoxPlayer != null) {
            videoEoxPlayer.videoStop();
            videoEoxPlayer = null;  // 確保釋放，避免未來 `videoPlay()` 重新建立失敗
        }
    }

    private void resetIdleTimer() {
        if (idleHandler != null) {
            idleHandler.removeCallbacks(idleRunnable);
        }

        idleRunnable = () -> {
            getLogs().info("⚠️ 無操作5分鐘，自動返回首頁");
            Intent intent = new Intent(FontendActivity.this, HomeActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            finish();
        };

        idleHandler.postDelayed(idleRunnable, IDLE_TIMEOUT);
    }

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();
//        resetIdleTimer(); // 每次互動都重設計時器
    }

    private String getNetworkDevice() {
        String networkDevice = getString(R.string.no_internet);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Network network = connectivityManager.getActiveNetwork();
            if (network != null) {
                NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
                if (capabilities != null) {
                    if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                            && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                        String signalStrengthString = "";
                        int signalStrength = 0;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            signalStrength = capabilities.getSignalStrength();
                        }
                        if (signalStrength > 0) {
                            signalStrengthString = signalStrength > -100 ? ":"+getString(R.string.powerful) : ":"+getString(R.string.weak);
                            signalStrengthString += "(" + signalStrength + ")";
                        }
                        if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                            networkDevice = getString(R.string.wireless_internet) + signalStrengthString;
                        } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                            networkDevice = getString(R.string.mobile_network) + signalStrengthString;
                        } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                            networkDevice = getString(R.string.wired_internet);
                        }
                    }
                }
            }
        } else if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            networkDevice = getString(R.string.network_device_str_unsupport);
        }
        return networkDevice;
    }

    private boolean checkPermissionByAccessFineLocation() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        }
        return true; // SDK < 23 時權限已在安裝時授予
    }

    private int getMobileSignalStrength() {
        if (checkPermissionByAccessFineLocation()) {
            try {
                TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                List<CellInfo> cellInfoList = telephonyManager.getAllCellInfo();
                if (cellInfoList != null && !cellInfoList.isEmpty()) {
                    for (CellInfo cellInfo : cellInfoList) {
                        if (cellInfo instanceof CellInfoLte) {
                            CellSignalStrengthLte signalStrength = ((CellInfoLte) cellInfo).getCellSignalStrength();
                            return signalStrength.getDbm();
                        }
                    }
                }
            } catch (SecurityException e) {
                getLogs().warning(e);
            } catch (Exception e) {
                getLogs().warning(e);
            }
        }
        return -1; // 無法獲取訊號強度
    }

    private void setBottomNavigation() {
        flowerFragment = new FlowerFragment(getHandlerMain());
        activeFragment = flowerFragment;

        if (MyApp.getInstance().getDevSet().isElectic()) {
            electricFragment = new ElectricFragment(getHandlerMain());
            activeFragment = flowerFragment;
        }

        ((FragmentAbstract) activeFragment).setUseStartOnSwitchFragment(true);

        getSupportFragmentManager().beginTransaction().add(binding.fragmentContainer.getId(), flowerFragment, "FLOWER").hide(flowerFragment).commit();

        if (MyApp.getInstance().getDevSet().isElectic()) {
            getSupportFragmentManager().beginTransaction().add(binding.fragmentContainer.getId(), electricFragment, "ELECTRIC").hide(electricFragment).commit();
        }

        getSupportFragmentManager().beginTransaction()
                .show(activeFragment)
                .commit();

        if (activeFragment instanceof FlowerFragment) {
            binding.buttonVmc.setBackgroundColor(Color.BLACK);
            binding.buttonVmc.setTextColor(Color.WHITE);
            if (MyApp.getInstance().getDevSet().isElectic()) {
                binding.buttonElectric.setBackgroundColor(Color.TRANSPARENT);
                binding.buttonElectric.setTextColor(Color.BLACK);
            }
        }

        if (activeFragment instanceof ElectricFragment) {
            binding.buttonVmc.setBackgroundColor(Color.TRANSPARENT);
            binding.buttonVmc.setTextColor(Color.BLACK);
            if (MyApp.getInstance().getDevSet().isElectic()) {
                binding.buttonElectric.setBackgroundColor(Color.BLACK);
                binding.buttonElectric.setTextColor(Color.WHITE);
            }
        }

       binding.buttonVmc.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               binding.buttonVmc.setBackgroundColor(Color.BLACK);
               binding.buttonVmc.setTextColor(Color.WHITE);
               if (MyApp.getInstance().getDevSet().isElectic()) {
                   binding.buttonElectric.setBackgroundColor(Color.TRANSPARENT);
                   binding.buttonElectric.setTextColor(Color.BLACK);
               }
               switchFragment(activeFragment, flowerFragment);
           }
       });

       binding.buttonElectric.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               binding.buttonVmc.setBackgroundColor(Color.TRANSPARENT);
               binding.buttonVmc.setTextColor(Color.BLACK);
               if (MyApp.getInstance().getDevSet().isElectic()) {
                   binding.buttonElectric.setBackgroundColor(Color.BLACK);
                   binding.buttonElectric.setTextColor(Color.WHITE);
               }
               switchFragment(activeFragment, electricFragment);
           }
       });

        if (MyApp.getInstance().getDevSet().isElectic()) {
            binding.buttonElectric.setVisibility(VISIBLE);
        } else {
            binding.buttonElectric.setVisibility(View.GONE);
        }

        binding.floatButtonPickupCode.setOnClickListener(view -> {
            new FontendPickupCodeDialog(getCtx(), getHandlerMain()).show();
        });

        binding.floatButtonPickupCode.setVisibility(VISIBLE);

       binding.floatButtonShoppingCart.setOnClickListener(view -> {
           getHandlerMain().start(getClass().getSimpleName(), Option.BUY_DIALOG_OPEN.getOption(), getString(R.string.detect_shopping_cart));
       });

        if (MyApp.getInstance().getDevSet().isShoppingCar()) {
            binding.floatButtonShoppingCart.setVisibility(VISIBLE);
        } else {
            binding.floatButtonShoppingCart.setVisibility(View.GONE);
        }

       if (reportOnScheduler != null) {
           reportOnScheduler.shutdown();
       }

        reportOnScheduler = new ReportShotTimeByScheduler(getHandlerMain());
        reportOnScheduler.start(1L, 10L, TimeUnit.SECONDS);

        binding.btnswitchlanTW.setOnClickListener(v -> switchLanguage("tw"));

        binding.btnswitchlanEn.setOnClickListener(v -> switchLanguage("en"));

        binding.btnswitchlanJa.setOnClickListener(v -> switchLanguage("ja"));

    }

    private void switchLanguage(String languageCode) {
        LanguageHelper.changeLanguage(this, languageCode);
        binding = ActivityFontendBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        this.connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);

        setBottomNavigation();
    }

    private void hiddenMultiLanguageButton(){
        binding.btnswitchlanTW.setVisibility(View.GONE);
        binding.btnswitchlanEn.setVisibility(View.GONE);
        binding.btnswitchlanJa.setVisibility(View.GONE);
    }

    private void showMultiLanguageButton(){
        binding.btnswitchlanTW.setVisibility(VISIBLE);
        binding.btnswitchlanEn.setVisibility(VISIBLE);
        binding.btnswitchlanJa.setVisibility(VISIBLE);
    }

    private class RestartHost extends HandlerMainScheduler {
        private int testCount = 0;
        public RestartHost(HandlerMain handlerMain) {
            super(handlerMain);
            testCount = 0;
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
            for (int testIndex=0; testIndex < 30; testIndex++) {
                if (testCount < 3) {
                    if (!MyApp.getInstance().isShowDialog()) {
                        getLogs().debug("RestartHost testCount:" + testCount);
                        testCount++;
                    } else {
                        testCount = 0;
                    }

                    try {
                        Thread.sleep(1000*20);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    break;
                }
            }

            if (testCount < 3) {
                return;
            }

            getTools().gotoActivity(RestartHostActivity.class);
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    private class ResetSlotNo extends HandlerMainScheduler {
        public ResetSlotNo(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {

            try {
                httpAPI.reportSlotPost();
            } catch (LogsParseException e) {
                throw new RuntimeException(e);
            } catch (LogsSettingEmptyException e) {
                throw new RuntimeException(e);
            }

        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    private class RemoteDelivery extends HandlerMainScheduler {
        private int testCount = 0;
        public RemoteDelivery(HandlerMain handlerMain) {
            super(handlerMain);
            testCount = 0;
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
//            for (int testIndex=0; testIndex < 30; testIndex++) {
//                if (testCount < 3) {
//                    if (!MyApp.getInstance().isShowDialog()) {
//                        getLogs().debug("RestartHost testCount:" + testCount);
//                        testCount++;
//                    } else {
//                        testCount = 0;
//                    }
//
//                    try {
//                        Thread.sleep(1000*20);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                } else {
//                    break;
//                }
//            }
//
//            if (testCount < 3) {
//                return;
//            }

            try {
                httpAPI.remoteDeliveryPost();
            } catch (LogsSettingEmptyException e) {
                throw new RuntimeException(e);
            } catch (LogsParseException e) {
                throw new RuntimeException(e);
            }

        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    private static class NfcCheckout extends HandlerMainScheduler {
        private int testCount = 0;
        public NfcCheckout(HandlerMain handlerMain) {
            super(handlerMain);
            testCount = 0;
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
            for (int testIndex=0; testIndex < 30; testIndex++) {
                if (testCount < 3) {
                    if (!MyApp.getInstance().isShowDialog()) {
                        getLogs().debug("NfcCheckout testCount:" + testCount);
                        testCount++;
                    } else {
                        testCount = 0;
                    }

                    try {
                        Thread.sleep(1000*20);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    break;
                }
            }

            if (testCount < 3) {
                return;
            }

            try {
                Rs232Dev comPort2 = new Rs232Dev(MyApp.getInstance().getComPort2ByNFCPay());
                DevNFCPay devNFCPay = new DevNFCPay();
                comPort2.send(devNFCPay.checkout());
                handlerMain.start(getClass().getSimpleName(), "刷卡機結帳啟動");
            } catch (LogsUnsupportedOperationException | LogsIOException e) {
                getLogs().warning(e);
            }
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    private class DetectTemp extends HandlerMainScheduler {
        private int testCount = 0;
        public DetectTemp(HandlerMain handlerMain) {
            super(handlerMain);
            testCount = 0;
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) throws IOException {
            Looper.prepare();  // ✅ 確保這個執行緒有 Looper
            for (int testIndex=0; testIndex < 30; testIndex++) {
                if (testCount < 3) {
                    if (!MyApp.getInstance().isShowDialog()) {
//                        getLogs().debug("RunToADPage testCount:" + testCount);
                        testCount++;
                    } else {
                        testCount = 0;
                    }

                    try {
                        Thread.sleep(1000*20);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    break;
                }
            }


            if (testCount < 3) {
                return;
            }

            //Looper.loop();  // ✅ 啟動事件迴圈
            HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

            for (UsbDevice device : deviceList.values()) {
                UsbSerialDriver driver = prober.probeDevice(device);
                if (driver != null) {
                    UsbDeviceConnection connection = usbManager.openDevice(driver.getDevice());
                    if (connection != null) {
                        UsbSerialPort port = driver.getPorts().get(0); // 取第一個port
                        port.open(connection);
                        port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

                        // 讀取資料（需另開 Thread）
                        new Thread(() -> {
                            byte[] buffer = new byte[128];
                            while (true) {
                                int len = 0;
                                try {
                                    len = port.read(buffer, 1000);
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                                if (len > 0) {
                                    String temp = new String(buffer, 0, len);
                                    getLogs().info("AAAAAAAAAAAAA "+temp);
                                    //Log.d("USB_DATA", "收到溫度：" + temp);
                                    //runOnUiThread(() -> getLogs().info("溫度: " + temp + " °C"));
                                }
                            }
                        }).start();
                    }
                }
            }

            // 👇 安全地結束 Looper，釋放這個 Thread
            Objects.requireNonNull(Looper.myLooper()).quitSafely(); // 或 quit() 根據需求

        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    public void RunDetectTemp() throws IOException {
//        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
//
//        for (UsbDevice device : deviceList.values()) {
//            UsbSerialDriver driver = prober.probeDevice(device);
//            if (driver != null) {
//                UsbDeviceConnection connection = usbManager.openDevice(driver.getDevice());
//                if (connection != null) {
//                    UsbSerialPort port = driver.getPorts().get(0); // 取第一個port
//                    port.open(connection);
//                    port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
//
//                    // 讀取資料（需另開 Thread）
//                    new Thread(() -> {
//                        byte[] buffer = new byte[128];
//                        while (true) {
//                            int len = 0;
//                            try {
//                                len = port.read(buffer, 1000);
//                            } catch (IOException e) {
//                                throw new RuntimeException(e);
//                            }
//                            if (len > 0) {
//                                String temp = new String(buffer, 0, len);
//                                getLogs().info("AAAAAAAAAAAAA "+temp);
//                                //Log.d("USB_DATA", "收到溫度：" + temp);
//                                //runOnUiThread(() -> getLogs().info("溫度: " + temp + " °C"));
//                            }
//                        }
//                    }).start();
//                }
//            }
//        }

        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

        for (UsbDevice device : deviceList.values()) {
            UsbSerialDriver driver = prober.probeDevice(device);
            if (driver != null) {
                UsbDeviceConnection connection = usbManager.openDevice(driver.getDevice());
                if (connection != null) {
                    UsbSerialPort port = driver.getPorts().get(0);
                    port.open(connection);
                    port.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

                    new Thread(() -> {
                        byte[] buffer = new byte[64];
                        StringBuilder receivedData = new StringBuilder();

                        while (true) {
                            try {
                                int len = port.read(buffer, 1000);
                                if (len > 0) {
                                    String incoming = new String(buffer, 0, len);

                                    receivedData.append(incoming);

                                    int newlineIndex;
                                    while ((newlineIndex = receivedData.indexOf("\n")) != -1) {
                                        String line = receivedData.substring(0, newlineIndex).trim();
                                        receivedData.delete(0, newlineIndex + 1); // 移除已處理資料
                                        machineDetectTemp = Double.parseDouble(line);
//                                        getLogs().info("AAAAAAAAAAAAAAAAAAAAAAAAAAA "+ machineDetectTemp);
                                        //runOnUiThread(() -> getLogs().info("溫度: " + line + " °C"));
                                    }
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                                break;
                            }
                        }
                    }).start();
                }
            }
        }
    }


    public class ReportShotTimeByScheduler extends HandlerMainScheduler {
        public ReportShotTimeByScheduler(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), Option.REPORT_AND_SHOT_TIME.getOption(), "start");
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    public class AddProductOnCountdown extends HandlerMainCountdown {
        public AddProductOnCountdown(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void close(HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), Option.BUY_DIALOG_OPEN.getOption(), "buy dialog open");
        }

        @Override
        protected void execute(long countdown, HandlerMain handlerMain) {
//            if (countdown == 20 || countdown == 10) {
//                handlerMain.start(getClass().getSimpleName(), "剩餘"+countdown+"秒");
//            }
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    private void switchFragment(Fragment from, Fragment to) {
        if (from != to) {
            if (from instanceof FragmentAbstract) {
                getLogs().info("change pay stop");
                ((FragmentAbstract) from).stopOnSwitchFragment();
            }

            getSupportFragmentManager().beginTransaction()
                    .hide(from)
                    .show(to)
                    .commit();
            activeFragment = to;

            if (to instanceof FragmentAbstract) {
                getLogs().info("change pay start");
                ((FragmentAbstract) to).startOnSwitchFragment();
            }
        }
    }

    public void callbackOnBackPressed() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        int backStackCount = fragmentManager.getBackStackEntryCount();
        if (backStackCount == 0) {
            // 沒有上一頁時，顯示提示訊息
            Toast.makeText(FontendActivity.this, getString(R.string.no_previous_page), Toast.LENGTH_SHORT).show();
        } else {
            // 有上一頁時，返回上一頁
            finish();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        if (electricFragment != null) {
            switchFragment(activeFragment, electricFragment);

            binding.buttonVmc.setBackgroundColor(Color.TRANSPARENT);
            binding.buttonVmc.setTextColor(Color.BLACK);
            binding.buttonElectric.setBackgroundColor(Color.BLACK);
            binding.buttonElectric.setTextColor(Color.WHITE);
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            if (event.getAction() == KeyEvent.ACTION_DOWN && event.isLongPress()) {
                Toast.makeText(this, getString(R.string.back_home), Toast.LENGTH_SHORT).show();
                Log.i("goto", "MainActivity");
                startActivity(new Intent(FontendActivity.this, MainActivity.class));
                return true;
            }
        }

        return super.dispatchKeyEvent(event);
    }

    private void saveData() {
        SlotsDao slotsDao = new SlotsDao(getCtx());
        slotsDao.deleteAll();
        slotsDao.insertAll(MyApp.getInstance().getSlotMap());
        slotsDao.close();
    }

    @Override
    protected void onResume() {
        super.onResume();
//        resetIdleTimer();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (idleHandler != null) {
            idleHandler.removeCallbacks(idleRunnable);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopOnSwitchFragment();

        if (networkCallback != null) {
            connectivityManager.unregisterNetworkCallback(networkCallback);
        }

        if (flowerFragment != null) {
            ((FragmentAbstract) flowerFragment).stopOnSwitchFragment();
        }

        if (MyApp.getInstance().getDevSet().isElectic()) {
            if (electricFragment != null) {
                ((FragmentAbstract) electricFragment).stopOnSwitchFragment();
            }
        }

        if (reportOnScheduler != null) {
            reportOnScheduler.shutdown();
            reportOnScheduler = null;
        }
    }
}